/* eslint-disable no-dupe-else-if */
type Box<T> = {
  readonly value: T;
};

function boxHasValue<T>(box: Box<T>, value: T): boolean {
  return box.value === value;
}
// @ts-expect-error - why?
boxHasValue({ value: 1 }, "hello");
// because value is  not contains box.value

function find<T>(needle: T, haystack: readonly T[]): boolean {
  return haystack.includes(needle);
}
// any why?
find(1, [1, 2, "hello"]);
// haystack has contains needle

declare function unBoxIf<T>(x: T | Box<T>): T;

declare function unBoxIfGood<Prepare, After = Prepare | Box<Prepare>>(
  x: After,
): void;

unBoxIf({ value: 1 });
// 总是不现实推倒出 unknown

declare function find2<T>(arr: readonly T[], func: (arg: T) => boolean): void;
function isNeat(sn: string | number | boolean): sn is number {
  return typeof sn === "number";
}

const x = find2([1, 2, 3], isNeat);

declare function find3<T>(
  arr: readonly T[],
  arr2: readonly T[],
  func: (arg: T) => boolean,
): void;

find3([1, 2, 3], [1, 2, "a", "b", "b"], isNeat);
// best match: string | number

declare function exec<T, U>(consumer: (arg: T) => U, producer: () => T): U;

exec(
  (arg) => arg.length,
  () => "hello",
);
/// ///////////////////////////////////////////

interface K {
  kind: string;
}
class A<T extends K = K> {
  a: T = null!;

  clientCode() {
    this.doCheck(this.a);
  }

  doCheck = Boolean;
}
// 实际的子类
type SpType = false | "required";
// 实际的父类
type SpTypePlus = false | "required" | "pattern";

type IsSub = SpType extends SpTypePlus ? true : false;
type IsExtends = never extends unknown ? true : false;

type Sf<in T> = <U>(sf: U) => void;

const sf: Sf<SpType> = <T>(sf: T) => sf;
const p = sf({} as SpType);

const sfPlus: Sf<SpTypePlus> = () => {
  if (Math.random()) {
    return "required";
  } else if (Math.random()) {
    return "pattern";
  }

  return false;
};
sfPlus("required");

let sfFalsy!: Sf<false>;
